<template>
  <li class="item flex items-center">
    <span v-if="Array.isArray(parentState)"
      style="margin-left:18px;">{{propName}}</span>
    <input v-else
      ref="propName"
      type="text"
      class="edit-input prop-name"
      :class="{error: !nameValid}"
      v-model="propName"
      @keydown.esc.capture.stop.prevent="cancelAdd()"
      @keydown.enter="submitAdd()">
    <span style="color:#fff;">:</span>
    <input ref="propValue"
      class="edit-input prop-value"
      :class="{error: !valueValid}"
      v-model="propValue"
      @keydown.esc.capture.stop.prevent="cancelAdd()"
      @keydown.enter="submitAdd()">
    <span class="flex items-center"
      v-if="isVaild">
      <button title="取消"
        @click.stop="cancelAdd">
        <a-icon type="close-circle"
          theme='filled'
          style="font-size:14px;" />
      </button>
      <button title="保存"
        @click.stop="submitAdd">
        <a-icon type="save"
          theme='filled'
          style="font-size:14px;" />
      </button>
    </span>
    <span v-else
      class="flex items-center"
      style="color:#ff6320; margin-left: 6px;">
      <a-icon type="warning"
        theme='filled'
        style="font-size:14px;" />
    </span>
  </li>
</template>
<script>
import { Icon } from 'ant-design-vue'
import { parse, transformSpecialTokens, transform } from './util'
// https://cn.vuejs.org/v2/style-guide/#组件-实例的选项的顺序-推荐
export default {
  name: 'add-item',
  components: {
    [Icon.name]: Icon
  },
  model: {},
  props: {
    parentState: {
      type: [Object, Array]
    }
  },
  data() {
    return {
      propName: null,
      propValue: transformSpecialTokens(
        JSON.stringify(transform(undefined)),
        true
      )
    }
  },
  computed: {
    nameValid() {
      return this.propName !== '' && !this.duplicateKey
    },
    valueValid() {
      try {
        parse(transformSpecialTokens(this.propValue, false))
        return true
      } catch (error) {
        return false
      }
    },
    isVaild() {
      return this.nameValid && this.valueValid
    },
    duplicateKey() {
      return this.parentState && this.parentState.hasOwnProperty(this.propName)
    }
  },
  watch: {},
  created() {},
  mounted() {
    this.addNewValue()

    this.$nextTick(() => {
      let ref = Array.isArray(this.parentState) ? 'propValue' : 'propName'
      const el = this.$refs[ref]
      if (!el) return
      el.focus()
      el.setSelectionRange(0, el.value.length)
    })
  },
  beforeDestroy() {},
  methods: {
    cancelAdd() {
      this.$emit('cancel-add')
    },
    submitAdd() {
      if (!this.isVaild) return
      const value = transformSpecialTokens(this.propValue, false)
      this.$emit('submit-add', {
        name: this.propName,
        value: parse(value, true)
      })
    },
    addNewValue() {
      let key
      if (Array.isArray(this.parentState)) {
        key = this.parentState.length
      } else {
        let i = 1
        while (this.parentState.hasOwnProperty((key = `prop${i}`))) i++
      }
      this.propName = key
    }
  }
}
</script>
<style lang="scss" scoped>
.item {
  padding-left: 20px;
}
.edit-input {
  height: 18px;
  padding: 2px 5px;
  border: none;
  border-radius: 2px;
  color: #c1fffb;
  background-color: #899a9a;
  font-family: Menlo, Monaco, 'Courier New', monospace;
  font-size: 12px;
  line-height: 1;
}
.prop-name {
  margin: 0 5px 0 13px;
}
.prop-value {
  margin: 0 5px;
}
button {
  display: flex;
  align-items: center;
  justify-content: center;

  width: 18px;
  height: 18px;
  margin-left: 6px;
  border: none;
  border-radius: 2px;

  color: #ffffffb5;
  background: transparent;
  &:hover {
    color: #fff;
    background-color: #5f7177b3;
  }
}
.flex {
  display: flex;
}
.justify-center {
  justify-content: center;
}
.items-center {
  align-items: center;
}
.error {
  box-shadow: 0 0 2px 1px inset #ff6320;
}
</style>
